/*
 * @Author       : Atonidas
 * @LastEditors  : Atonidas
 * @LastEditTime : 2023-09-14 01:01:04
 * @FilePath     : \multiplex_controller\User\Encoder\Encoder.c
 * @Description  : 编码器基础代码，含中断函数、进程服务函数
 */

#include "Encoder\Encoder.h"
#include <stdlib.h>
#include <string.h>

EncoderData encoders[MAX_ENCODERS];             // 编码器数据结构体数组
EncoderService encoder_services[MAX_ENCODERS];  // 编码器服务函数结构体数组
uint8_t numEncoders = 0;                        // 当前已注册的编码器数量

/**
 * @description:        编码器子项注册函数，数量自动累加，但不能超过 MAX_ENCODERS
 * @param initialValue  子项初始值
 * @param limit         子项最大计数值
 * @param step          子项转换步进
 * @param name          子项词条
 * @return 
 */
void registerEncoder(unsigned short initialValue, unsigned short limit, unsigned short step, void (*service_callback)(), char *name)
{
    if (numEncoders < MAX_ENCODERS) {
        encoders[numEncoders].value = initialValue;
        encoders[numEncoders].limit = limit;

        encoder_services[numEncoders].history_value    = initialValue;
        encoder_services[numEncoders].step             = step;
        encoder_services[numEncoders].service_callback = service_callback;

        strcpy(encoder_services[numEncoders].name, name);

        numEncoders++;
    } else {
        // 超过最大编码器数量，无法注册新编码器
        // 可以添加错误处理或记录日志等操作
    }
}

/**
 * @description:    获取编码器值
 * @param index     子项编号
 * @return          子项编码器值 * 转换步进
 */
unsigned short getEncoderValue(unsigned char index)
{
    if (index >= 0 && index < numEncoders) {
        return encoders[index].value * encoder_services[index].step;
    } else {
        // 索引超出范围，无法获取编码器数值
        // 可以添加错误处理或记录日志等操作
        return 0; // 返回默认值
    }
}

/**
 * @description: 编码器旋钮中断服务函数，使用前请定义通道B及通道C按键宏定义
 * @return 
 */
void Encoder_IT_Task(void)
{
    static unsigned char point = 0;
    unsigned short limit_min;
    EncoderData *m_encoder;

    if (EC_READ_KEY()) {
        point     = 0; // KEY按下时更改0通道
        limit_min = 1; // 0通道为主菜单通道，不允许选到自己
    } else {
        point     = encoders[0].value;
        limit_min = 0;
    }

    m_encoder = &encoders[point];

    if (EC_READ_PIN()) {
        m_encoder->value = (m_encoder->value + 1 <= m_encoder->limit) ? m_encoder->value + 1 : limit_min;
    } else {
        m_encoder->value = (m_encoder->value - 1 >= limit_min) ? m_encoder->value - 1 : m_encoder->limit;
    }
}

/**
 * @description: 编码器按键服务函数，进程中调用；当前值和历史值不同时进入相应回调函数
 * @return 
 */
void encoderServiceTask()
{
    for (unsigned char i = 0; i < numEncoders; i++) {
        unsigned short current_value = getEncoderValue(i);
        unsigned short history_value = encoder_services[i].history_value;

        if (current_value != history_value) {
            encoder_services[i].service_callback();            // 执行服务回调函数
            encoder_services[i].history_value = current_value; // 更新历史值
        }
    }
}